//
//  MSUserManager.m
//  FiveDegree
//
//  Created by apple on 2020/1/14.
//  Copyright © 2020 YYB. All rights reserved.
//

#import "MSUserManager.h"
#import <BGFMDB/BGFMDB.h>
#import "NSObject+SaveModelToKeyedArchiver.h"
// #import "TheOne_LocUpdateModel.h"
// #import "TheCheckLocationCityModel.h"
// #import "One_UserBaseinfoService.h"
#import "MJExtension.h"
//#import "HeaderConfig.h"
#import "MBProgressHUD+JDragon.h"

#define kCheckLocationModel @"TheCheckLocationCityModel"
#define kUserInfoModel @"UserInfoModel"

@interface MSUserManager ()
@property(nonatomic, assign, readwrite) BOOL can_use;

@end

@implementation MSUserManager

static MSUserManager *instance;

+ (instancetype)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
      instance = [[self alloc] init];
      // 更新用户信息
      //         [instance uploadUserBaseInfo];
    });
    return instance;
}

- (userInfoModel *)userModel {
    NSArray *ar = [userInfoModel bg_findAll:@"UserInfo"];
    if (ar.count > 0) {
        userInfoModel *userModel = ar.firstObject;
        return userModel;
    }
    return [userInfoModel new];
}

- (void)saveUserInfoModel:(userInfoModel *)userModel {
    // 存本地数据库
    userModel.bg_tableName = @"UserInfo";
    [userModel bg_saveOrUpdate];

    [userModel saveDataToLocalWithUniqueFlagKey:kUserInfoModel];
}

#pragma mark -
- (TheCheckLocationCityModel *)checkLocModel {
    Class modelClass = NSClassFromString(@"TheCheckLocationCityModel");
    if (modelClass) {
        id instance = [modelClass new];
        SEL selector = @selector(getDataFromLocalWithUniqueFlagKey:);
        if ([instance respondsToSelector:selector]) {
            id checkModel = [instance performSelector:selector withObject:kCheckLocationModel];
            return checkModel;
        }
    }
    return nil;
}

- (void)saveCheckLocModel:(id)checkLocModel {
    SEL selector = @selector(saveDataToLocalWithUniqueFlagKey:);
    if ([checkLocModel respondsToSelector:selector]) {
        [checkLocModel performSelector:selector withObject:kCheckLocationModel];
    }
}

- (void)clearAllModel {
    id checkModel = [self checkLocModel];
    SEL removeSelector = @selector(removeDataFromLocalWithUniqueFlagKey:);
    if ([checkModel respondsToSelector:removeSelector]) {
        [checkModel performSelector:removeSelector withObject:kCheckLocationModel];
    }
    [userInfoModel bg_clear:@"UserInfo"];
    self.userModel = [[userInfoModel alloc] init];
}

- (void)checkUserLocation:(void (^)(BOOL can_use))locationBlock {
    // Dynamically get the TheOne_LocUpdateModel class
    Class locUpdateClass = NSClassFromString(@"TheOne_LocUpdateModel");

    if (locUpdateClass) {
        // Create an instance of TheOne_LocUpdateModel
        id locUpdateModel = [[locUpdateClass alloc] init];

        // Define the selector for locationUploadSuccess:fail:
        SEL uploadSelector = NSSelectorFromString(@"locationUploadSuccess:fail:");

        if ([locUpdateModel respondsToSelector:uploadSelector]) {
            // Suppress performSelector leak warnings
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

            // Define the success block
            void (^successBlock)(id) = ^(id responseObject) {
              if ([responseObject[@"code"] intValue] == 200) {
                  // Dynamically create TheCheckLocationCityModel
                  Class checkModelClass = NSClassFromString(@"TheCheckLocationCityModel");
                  if (checkModelClass) {
                      id checkModel = [checkModelClass mj_objectWithKeyValues:responseObject[@"data"]];
                      [self saveCheckLocModel:checkModel];

                      if (locationBlock) {
                          // Assuming checkModel has a property 'can_use'
                          BOOL canUse = [[checkModel valueForKey:@"can_use"] boolValue];
                          locationBlock(canUse);
                          self.can_use = canUse;
                      }
                  }
              }
            };

            // Define the fail block
            void (^failBlock)(NSError *, NSString *) = ^(NSError *error, NSString *errorStr) {
              NSLog(@"errorStr = %@", errorStr);
              if (errorStr.length > 0) {
                  [MBProgressHUD showSuccessMessage:errorStr];
              }
            };

            // Perform the selector with the blocks
            // Since performSelector:withObject: only accepts two parameters, and our method has two blocks,
            // we can pass them directly.
            [locUpdateModel performSelector:uploadSelector withObject:successBlock withObject:failBlock];

#pragma clang diagnostic pop
        } else {
            NSLog(@"TheOne_LocUpdateModel does not respond to locationUploadSuccess:fail:");
        }
    } else {
        NSLog(@"TheOne_LocUpdateModel class not found");
    }
}

- (void)uploadUserBaseInfo {
    // 动态获取 One_UserBaseinfoService 类
    Class infoServiceClass = NSClassFromString(@"One_UserBaseinfoService");

    if (infoServiceClass) {
        // 创建 One_UserBaseinfoService 的实例
        id infoService = [[infoServiceClass alloc] init];

        // 定义 selector 对应 request:fail: 方法
        SEL requestSelector = NSSelectorFromString(@"requst:fail:");

        if ([infoService respondsToSelector:requestSelector]) {
            // 忽略 performSelector 的警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

            // 定义成功块
            void (^successBlock)(id) = ^(id responseObject) {
              NSDictionary *data = responseObject[@"data"];
              if ([data isKindOfClass:[NSDictionary class]] && data.allKeys.count > 0) {
                  // 动态创建 userInfoModel 实例
                  Class userInfoModelClass = NSClassFromString(@"userInfoModel");
                  if (userInfoModelClass) {
                      id userinfoModel = [userInfoModelClass performSelector:@selector(initDictForModel:) withObject:data[@"user_info"]];

                      // 以下数据未返回，取登录时数据
                      [userinfoModel setValue:self.userModel.token forKey:@"token"];
                      [userinfoModel setValue:@(self.userModel.user_status) forKey:@"user_status"];
                      [userinfoModel setValue:self.userModel.login_model forKey:@"login_model"];

                      [self saveUserInfoModel:userinfoModel];
                  }
              }
            };

            // 定义失败块
            void (^failBlock)(NSError *, NSString *) = ^(NSError *error, NSString *errorStr) {
              NSLog(@"errorStr = %@", errorStr);
              // 可以在这里添加错误处理逻辑，例如显示提示信息
              if (errorStr.length > 0) {
                  [MBProgressHUD showSuccessMessage:errorStr];
              }
            };

            // 创建方法签名并调用方法
            // 由于 performSelector 不支持多个参数或块，可以使用 NSInvocation
            NSMethodSignature *signature = [infoService methodSignatureForSelector:requestSelector];
            if (signature) {
                NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
                [invocation setSelector:requestSelector];
                [invocation setTarget:infoService];

                // 设置参数，注意索引从 2 开始，因为 0 和 1 是隐藏参数 self 和 _cmd
                if (successBlock) {
                    [invocation setArgument:&successBlock atIndex:2];
                }
                if (failBlock) {
                    [invocation setArgument:&failBlock atIndex:3];
                }

                [invocation invoke];
            } else {
                NSLog(@"One_UserBaseinfoService does not respond to requst:fail:");
            }

#pragma clang diagnostic pop
        } else {
            NSLog(@"One_UserBaseinfoService does not respond to requst:fail:");
        }
    } else {
        NSLog(@"One_UserBaseinfoService class not found");
    }
}

@end
